package bb.lanxing.util;

import static bb.lanxing.common.config.Constants.FOLDER_LOGGER;

import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.DiskLogAdapter;
import com.orhanobut.logger.Logger;
import com.orhanobut.logger.Printer;

import android.os.Handler;
import android.os.HandlerThread;

import androidx.annotation.StringRes;

import bb.lanxing.App;
import bb.lanxing.util.log.CustomCsvFormatStrategy;
import bb.lanxing.util.log.CustomDiskLogStrategy;

public class Log {
	// 默认标签级别为 Log.INFO, 如果想打开对应标签级别的log
	// adb shell setprop persist.log.tag.[TAG] [D]
	// TAG 为 特定标签
	// D 为对应的级别,可以简写,下面为对应的级别, SILENT 为关掉对应 标签的所有 log
	// VERBOSE,DEBUG,INFO,WARN,ERROR,FATA,SILENT
	/**
	 * public static final int VERBOSE = 2;
	 * public static final int DEBUG = 3;
	 * public static final int INFO = 4;
	 * public static final int WARN = 5;
	 * public static final int ERROR = 6;
	 * public static final int ASSERT = 7;
	 */
	// 比设定level大的 log 特定tag 才能输出
	/**
	 * 举例
	 * 比如调用
	 * public static void logv(String tag, String msg) {
	 * 默认的情况,这是不会输出对应 tag 的 log
	 * 虽然 它也调用
	 * android.util.Log.v(tag, msg);
	 * 如果想要输出log,必须做以下操作
	 * / adb shell setprop persist.log.tag.[tag] V
	 * [] 中的tag为传入的 具体标签
	 */
	private static final String TAG = "lanxing";
	private static final boolean userNativeLog = true;

	/**
	 *
	 */
	private static boolean isLoggingEnabled(String tag, int level) {
		return android.util.Log.isLoggable(tag, level);
	}

	public static void init() {
		if (!userNativeLog) {
			Logger.addLogAdapter(new AndroidLogAdapter());
		}
		String buildExternalDirectoryPath = AppFileUtils.buildExternalDirectoryPath(FOLDER_LOGGER);
		HandlerThread handlerThread = new HandlerThread("AndroidFileLogger");
		handlerThread.start();
		Handler handler = new CustomDiskLogStrategy.WriteHandler(handlerThread.getLooper(), buildExternalDirectoryPath, CustomDiskLogStrategy.MAX_BYTES);
		CustomCsvFormatStrategy csvFormatStrategy = CustomCsvFormatStrategy.newBuilder().logStrategy(new CustomDiskLogStrategy(handler)).build();
		Logger.addLogAdapter(new DiskLogAdapter(csvFormatStrategy));
	}

	public static void logd(@StringRes int i) {
		log(TAG, App.getContext().getString(i), android.util.Log.DEBUG);
	}

	public static void logd(String msg) {
		log(TAG, msg, android.util.Log.DEBUG);
	}

	public static void logd(String tag, String msg) {
		log(tag, msg, android.util.Log.DEBUG);
	}

	public static void logv(String tag, String msg) {
		log(tag, msg, android.util.Log.VERBOSE);
	}

	public static void logw(String tag, String msg) {
		log(tag, msg, android.util.Log.WARN);
	}

	public static void logi(String tag, String msg) {
		log(tag, msg, android.util.Log.INFO);
	}

	public static void loge(String tag, String msg) {
		log(tag, msg, android.util.Log.ERROR);
	}

	public static void wtf(String tag, String msg) {
		log(tag, msg, android.util.Log.VERBOSE);
	}

	public static void d(@StringRes int i) {
		log(TAG, App.getContext().getString(i), android.util.Log.DEBUG);
	}

	public static void d(String msg) {
		log(TAG, msg, android.util.Log.DEBUG);
	}

	public static void d(String tag, String msg) {
		log(tag, msg, android.util.Log.DEBUG);
	}

	public static void v(String tag, String msg) {
		log(tag, msg, android.util.Log.VERBOSE);
	}

	public static void v(String msg) {
		log(TAG, msg, android.util.Log.VERBOSE);
	}

	public static void w(String tag, String msg) {
		log(tag, msg, android.util.Log.WARN);
	}

	public static void i(String tag, String msg) {
		log(tag, msg, android.util.Log.INFO);
	}

	public static void i(String msg) {
		log(TAG, msg, android.util.Log.INFO);
	}

	public static void e(String msg, Throwable th) {
		log(TAG, msg, android.util.Log.ERROR, th);
	}

	public static void e(String tag, String msg, Throwable th) {
		log(tag, msg, android.util.Log.ERROR, th);
	}

	public static void e(String tag, String msg) {
		log(tag, msg, android.util.Log.ERROR);
	}

	private static void log(String tag, String msg, int level) {
		log(tag, msg, level, null);
	}

	private static void log(String tag, String msg, int level, Throwable th) {
		if (isLoggingEnabled(tag, level)) {
			if (userNativeLog) {
				android.util.Log.println(level, tag, msg);
			}
			Printer logger = Logger.t(tag);
			if (logger != null) {
				logger.log(level, tag, msg, th);
			}
		}
	}
}
